#ifndef __ATLCTRLWR_H__
#define __ATLCTRLWR_H__

/////////////////////////////////////////////////////////////////////////////
// CRecentCommandBarCtrl - ATL implementation of Command Bars
//
// Written by Bjarke Viksoe (bjarke@viksoe.dk)
// Copyright (c) 2001 Bjarke Viksoe.
//
// Overrides the original WTL CCommandBarCtrl.
// Define _WTL_USE_MDI in stdafx.h if you need the MDI version.
//
// Separators must be written as "-" strings. If not, they
// will not be ownerdrawn.
// Add menu Command IDs to the "recent" list using AddRecent().
//
// This code may be used in compiled form in any way you desire. This
// file may be redistributed by any means PROVIDING it is 
// not sold for profit without the authors written consent, and 
// providing that this notice and the authors name is included. 
//
// This file is provided "as is" with no expressed or implied warranty.
// The author accepts no liability if it causes any damage to you or your
// computer whatsoever. It's free, so don't hassle me about it.
//
// Beware of bugs.
//

#pragma once

#ifndef __cplusplus
   #error ATL requires C++ compilation (use a .cpp suffix)
#endif

#ifndef __ATLCTRLW_H__
   #error atlctrlwr.h requires atlctrlw.h to be included first
#endif

#if (_WTL_VER < 0x0700)
   #error This file requires WTL version 7.0 or higher
#endif


#ifndef ID_MENU_EXPANDER
#define ID_MENU_EXPANDER WM_USER+321
#endif // ID_MENU_EXPANDER

#ifndef ODS_NOACCEL
#define ODS_NOACCEL         0x0100
#endif // ODS_NOACCEL

#ifndef DT_HIDEPREFIX
#define DT_HIDEPREFIX       0x00100000
#endif // DT_HIDEPREFIX


// This hack allows us to have a SDI and MDI commandbar (but only one).
// Add this MDI define if you're building a MDI app.
#ifndef _WTL_USE_MDI
#define COMMANDBAR_CLASS CCommandBarCtrlImpl
#else
#define COMMANDBAR_CLASS CMDICommandBarCtrlImpl
#endif

template <class T, class TBase = CCommandBarCtrlBase, class TWinTraits = CControlWinTraits>
class ATL_NO_VTABLE CRecentCommandBarCtrlImpl : public COMMANDBAR_CLASS< T, TBase, TWinTraits >
{
public:
  DECLARE_WND_SUPERCLASS(NULL, TBase::GetWndClassName())

  typedef COMMANDBAR_CLASS< T,TBase,TWinTraits > TCtrlBase;

  // Declarations
  
  struct _MenuItemData2 : TCtrlBase::_MenuItemData // menu item data
  {
    bool fHidden;
    bool fPrevHidden;
    bool fNextHidden;
    //
    bool fExpander;
    bool fSeparator;
  };

  CSimpleMap<UINT, BOOL> m_mapRecent;
  BOOL m_bShowRecent;
  int m_iPopupMenu;
  CBrush m_hbrBack;

   // Message map and handlers
   
   BEGIN_MSG_MAP(CRecentCommandBarCtrlImpl)
      MESSAGE_HANDLER(WM_INITMENUPOPUP, OnInitMenuPopup)
      MESSAGE_HANDLER(WM_MENUSELECT, OnMenuSelect)
      COMMAND_ID_HANDLER(ID_MENU_EXPANDER, OnRecentExpand)
      CHAIN_MSG_MAP( TCtrlBase )
   ALT_MSG_MAP(1)      // Parent window messages
      MESSAGE_HANDLER(WM_COMMAND, OnCommandHandler)
      CHAIN_MSG_MAP_ALT( TCtrlBase, 1 )
   ALT_MSG_MAP(2)      // MDI client window messages
      CHAIN_MSG_MAP_ALT( TCtrlBase, 2 )
   ALT_MSG_MAP(3)      // Message hook messages
      CHAIN_MSG_MAP_ALT( TCtrlBase, 3 )
   END_MSG_MAP()

   CRecentCommandBarCtrlImpl()
      : m_bShowRecent(FALSE)
   {
      CWindowDC dc(NULL);
      int nBitsPerPixel = dc.GetDeviceCaps(BITSPIXEL);
      if( nBitsPerPixel > 8 ) {
         COLORREF clrBtnHilite = ::GetSysColor(COLOR_BTNHILIGHT);
         COLORREF clrBtnFace = ::GetSysColor(COLOR_BTNFACE);
         COLORREF clrLight = 
            RGB( GetRValue(clrBtnFace) + ((GetRValue(clrBtnHilite) - GetRValue(clrBtnFace)) / 2),
                 GetGValue(clrBtnFace) + ((GetGValue(clrBtnHilite) - GetGValue(clrBtnFace)) / 2),
                 GetBValue(clrBtnFace) + ((GetBValue(clrBtnHilite) - GetBValue(clrBtnFace)) / 2)
               );
         m_hbrBack.CreateSolidBrush(clrLight);
      }
      else {
         COLORREF crTxt = dc.SetTextColor(::GetSysColor(COLOR_BTNFACE));
         COLORREF crBk = dc.SetBkColor(::GetSysColor(COLOR_BTNHILIGHT));
         m_hbrBack =  CDCHandle::GetHalftoneBrush();
         dc.SetTextColor(crTxt);
         dc.SetBkColor(crBk);
      }
   }

   // Operations

   void AddRecent(UINT id)
   {
      m_mapRecent.Add(id,TRUE);
   }

   void RemoveRecent(UINT id)
   {
      m_mapRecent.Remove(id);
   }

   void SetShowRecent(BOOL f)
   {
      m_bShowRecent = f;
   }

   // Implementation - Message handlers

   LRESULT OnRecentExpand(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/)
   {
      m_bShowRecent = TRUE;
      DoPopupMenu(m_iPopupMenu, false);
      return 0;
   }

   LRESULT OnCommandHandler(UINT /*uMsg*/, WPARAM wParam, LPARAM /*lParam*/, BOOL& bHandled)
   {
      AddRecent(LOWORD(wParam));
      m_bShowRecent = FALSE;
      bHandled = FALSE;
      return 0;
   }

   LRESULT OnInitMenuPopup(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
   {
      if( (BOOL)HIWORD(lParam) ) { 
         // System menu, do nothing
         bHandled = FALSE;
         return 1;
      }
      if( !(m_bAttachedMenu || m_bMenuActive) ) { 
         // Not attached or ours, do nothing
         bHandled = FALSE;
         return 1;
      }

#ifdef _CMDBAR_EXTRA_TRACE
      ATLTRACE2(atlTraceUI, 0, "RecentCmdBar - OnInitMenuPopup\n");
#endif

      // Remember which menu popped up
      m_iPopupMenu = m_nPopBtn;

      // Forward to the parent or subclassed window, so it can handle update UI
      LRESULT lRet = 0;
      if( m_bAttachedMenu )
         lRet = DefWindowProc(uMsg, wParam, (lParam || m_bContextMenu) ? lParam : GetHotItem());
      else
         lRet = m_wndParent.DefWindowProc(uMsg, wParam, (lParam || m_bContextMenu) ? lParam : GetHotItem());

      // Convert menu items to ownerdraw, add our data
      if( m_bImagesVisible ) {
         CMenuHandle menuPopup = (HMENU)wParam;
         ATLASSERT(menuPopup.m_hMenu != NULL);

         _MenuItemData2* pLastMI = NULL;
         TCHAR szString[_nMaxMenuItemTextLength];
         BOOL bRet;
         bool bHadDiscardedItems = false;
         bool bWasLastItemHidden = true;
         bool bHidden = false;

         // Convert all menu items to ownerdrawn
         for( int i=0; i < menuPopup.GetMenuItemCount(); i++ ) {
            szString[0] = _T('\0');
            CMenuItemInfo mii;
            mii.fMask = MIIM_CHECKMARKS | MIIM_DATA | MIIM_ID | MIIM_STATE | MIIM_SUBMENU | MIIM_TYPE;
            mii.dwTypeData = szString;
            mii.cch = _nMaxMenuItemTextLength;
            bRet = menuPopup.GetMenuItemInfo(i, TRUE, &mii);
            ATLASSERT(bRet);

            if( mii.fType & MFT_SEPARATOR ) continue;    // We don't wanna mess with separator from system
            if( mii.fType & MFT_OWNERDRAW ) continue;    // We don't wanna mess with ownerdrawn item (from previous runs or custom)
            ATLASSERT( ::lstrlen(szString)>0 );          // No empty strings

            // Add our private data
            mii.fMask = MIIM_DATA | MIIM_TYPE | MIIM_STATE;
            _MenuItemData2* pMI = NULL;
            ATLTRY(pMI = new _MenuItemData2);
            ATLASSERT(pMI!=NULL);
            if( pMI==NULL ) return 0;

            pMI->fType = mii.fType;
            pMI->fState = mii.fState;

            // Check for menu separator or turn into an ownerdrawn item...
            // Separators SHOULD be the string "-", but we will turn
            // them into real (ownerdrawn) separators here...
            if( ::lstrcmp(szString, _T("-"))==0 ) {
               mii.fType = MFT_SEPARATOR | MFT_OWNERDRAW;
               pMI->fSeparator = true; 
            }
            else {
               mii.fType |= MFT_OWNERDRAW;
               pMI->fSeparator = false;
            }

            // Is this item hidden?
            bHidden = !m_mapRecent.Lookup(mii.wID);
            if( pMI->fSeparator ) bHidden = bWasLastItemHidden; // separators get visibility from last item
            if( mii.hSubMenu!=NULL ) bHidden = false;           // items with submenus are never hidden
            if( m_bContextMenu ) bHidden = false;               // context menus are of course not hidden
            // Check if it is invisible then
            if( bHidden && !m_bShowRecent ) {
               // Turn rarely used items into menu separators (fixes keyboard navigation)
               mii.fType = MFT_SEPARATOR | MFT_OWNERDRAW;
            }
            // If item is not hidden, make adjacent separator visible
            if( !bHidden && pLastMI ) {
               if( pLastMI->fSeparator ) pLastMI->fHidden = false;
            }
            //
            pMI->fHidden = bHidden;
            pMI->fPrevHidden = pMI->fNextHidden = false;
            if( pLastMI!=NULL ) {
               pMI->fPrevHidden = pLastMI->fHidden;
               pLastMI->fNextHidden = bHidden;
            }
            pMI->fExpander = false;
            //
            pMI->iButton = -1;
            for( int j=0; j < m_arrCommand.GetSize(); j++ ) {
               if(m_arrCommand[j] == mii.wID) {
                  pMI->iButton = j;
                  break;
               }
            }
            //
            pMI->lpstrText = NULL;
            ATLTRY(pMI->lpstrText = new TCHAR[::lstrlen(szString) + 1]);
            ATLASSERT(pMI->lpstrText);
            ::lstrcpy(pMI->lpstrText, szString);
            mii.dwItemData = (ULONG_PTR)pMI;
            //
            bRet = menuPopup.SetMenuItemInfo(i, TRUE, &mii);
            ATLASSERT(bRet);

            pLastMI = pMI;
            bHadDiscardedItems |= bHidden; // Had ANY hidden items?
            bWasLastItemHidden = bHidden;  // Record visibility of previous
         }

         // Should we insert the expander at the bottom?
         if( bHadDiscardedItems && !m_bShowRecent ) {
            CMenuItemInfo mii;
            mii.fMask = MIIM_ID | MIIM_DATA | MIIM_TYPE | MIIM_STATE;
            mii.fType = MFT_OWNERDRAW;
            _MenuItemData2* pMI = NULL;
            ATLTRY(pMI = new _MenuItemData2);
            ATLASSERT(pMI != NULL);
            if( pMI != NULL ) {
               mii.wID = ID_MENU_EXPANDER;
               mii.fState = MFS_ENABLED;
               mii.dwItemData = (ULONG_PTR)pMI;
               pMI->fHidden = false;
               pMI->fPrevHidden = false;
               pMI->fNextHidden = false;
               pMI->fState = mii.fState;
               pMI->fType = mii.fType;
               pMI->fExpander = true;
               pMI->fSeparator = false;
               ATLTRY(pMI->lpstrText = new TCHAR[1]);
               ATLASSERT(pMI->lpstrText);
               ::lstrcpy(pMI->lpstrText, _T(""));
               bRet = menuPopup.InsertMenuItem(999, TRUE, &mii);
               ATLASSERT(bRet);
            }
         }

         // Add it to the list
         m_stackMenuHandle.Push(menuPopup.m_hMenu);
      }

      return lRet;
   }

   LRESULT OnMenuSelect(UINT /*uMsg*/, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
   {
      // Check if a menu is closing, do a cleanup
      if( HIWORD(wParam)==0xFFFF && lParam==NULL ) {
#ifdef _CMDBAR_EXTRA_TRACE
         ATLTRACE2(atlTraceUI, 0, "RecentCmdBar - OnMenuSelect - CLOSING!!!!\n");
#endif
         // Remove expanders (if present)
         int cItem = m_stackMenuHandle.GetSize() - 1;
         while( cItem >= 0 ) {
            HMENU hMenu = m_stackMenuHandle[cItem];
            if( hMenu != NULL ) {
               CMenuItemInfo mii;
               mii.fMask = MIIM_DATA | MIIM_TYPE;
               if( ::GetMenuItemInfo(hMenu, ID_MENU_EXPANDER, FALSE, &mii) ) {
                  _MenuItemData2* pMI = (_MenuItemData2*)mii.dwItemData;
                  if( pMI!=NULL && pMI->IsCmdBarMenuItem() ) {
                     delete [] pMI->lpstrText;
                     pMI->dwMagic = 0x6666;
                     delete pMI;
                  }
                  ::RemoveMenu(hMenu, ID_MENU_EXPANDER, MF_BYCOMMAND);
               }
            }
            cItem--;
         }
      }
      bHandled = FALSE;
      return 0;
   }

   // Implementation - ownerdraw overrideables and helpers
   
   void DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct)
   {
      _MenuItemData2* pmd = (_MenuItemData2*)lpDrawItemStruct->itemData;
      CDCHandle dc = lpDrawItemStruct->hDC;
      RECT rcItem = lpDrawItemStruct->rcItem;

      if( pmd->fHidden && !m_bShowRecent ) return;

      CBrushHandle hbrBack( pmd->fHidden ? m_hbrBack : (HBRUSH)LongToPtr(COLOR_MENU+1) );

      if( m_bShowRecent ) {
         if( pmd->fHidden && !pmd->fPrevHidden ) {
            RECT rc = rcItem;
            rc.bottom = rc.top+1;
            dc.DrawEdge(&rc, EDGE_SUNKEN, BF_TOP);   // draw box line
            rcItem.top += 1;
         }
         if( pmd->fHidden && !pmd->fNextHidden ) {
            RECT rc = rcItem;
            rc.top = rc.bottom-1;
            dc.DrawEdge(&rc, EDGE_SUNKEN, BF_BOTTOM);   // draw box line
            rcItem.bottom -= 1;
         }
      }

      if( pmd->fSeparator ) {
         // Draw separator
         dc.FillRect(&rcItem, hbrBack);
         RECT rc = rcItem;
         ::InflateRect(&rc, -16,0);             // indent separator like Word2000 does
         rc.top += (rc.bottom - rc.top) / 2;    // vertical center
         dc.DrawEdge(&rc, EDGE_ETCHED, BF_TOP); // draw separator line
      }
      else if( pmd->fExpander ) {
         // Draw separator
         bool bSelected = (lpDrawItemStruct->itemState & ODS_SELECTED)!=0;
         dc.FillRect(&rcItem, hbrBack);
         RECT rc = rcItem;
         ::InflateRect(&rc, -4,-1);
         bool bButton = (::GetAsyncKeyState(VK_LBUTTON) & 0x8000)!=0;
         dc.DrawFrameControl( &rc, DFC_SCROLL, DFCS_SCROLLDOWN | (bSelected ? 0 : DFCS_FLAT) | (bButton ? DFCS_PUSHED : 0) );
      }
      else {     
         // Draw standard item
         bool bSelected = (lpDrawItemStruct->itemState & ODS_SELECTED)!=0;
         bool bChecked = (lpDrawItemStruct->itemState & ODS_CHECKED)!=0;
         bool bDisabled = (lpDrawItemStruct->itemState & ODS_GRAYED)!=0;
         bool bDrawAccel = (lpDrawItemStruct->itemState & ODS_NOACCEL)==0;
         bool bHasImage = false;

         if( LOWORD(lpDrawItemStruct->itemID) == (WORD)-1 ) bSelected = false;
         RECT rcButn = { rcItem.left, rcItem.top, rcItem.left + m_szButton.cx, rcItem.top + m_szButton.cy };         // button rect
         ::OffsetRect(&rcButn, 0, ((rcItem.bottom - rcItem.top) - (rcButn.bottom - rcButn.top)) / 2);   // center vertically

         dc.FillRect(&rcItem, hbrBack);

         int iButton = pmd->iButton;
         if( iButton >= 0 ) {
            bHasImage = true;

            // Calc drawing point
            SIZE sz = { rcButn.right - rcButn.left - m_szBitmap.cx, rcButn.bottom - rcButn.top - m_szBitmap.cy };
            sz.cx /= 2;
            sz.cy /= 2;
            POINT point = { rcButn.left + sz.cx, rcButn.top + sz.cy };

            // Draw disabled or normal
            if( !bDisabled ) {
               // Normal - fill background depending on state
               if( !bChecked || bSelected ) {
                  HBRUSH hbr = hbrBack;
                  if( bChecked && !bSelected ) hbr = (HBRUSH)LongToPtr((COLOR_3DLIGHT + 1));
                  dc.FillRect(&rcButn, hbr);
               }
               else {
                  COLORREF crTxt = dc.SetTextColor(::GetSysColor(COLOR_BTNFACE));
                  COLORREF crBk = dc.SetBkColor(::GetSysColor(COLOR_BTNHILIGHT));
                  CBrush hbr(CDCHandle::GetHalftoneBrush());
                  dc.SetBrushOrg(rcButn.left, rcButn.top);
                  dc.FillRect(&rcButn, hbr);
                  dc.SetTextColor(crTxt);
                  dc.SetBkColor(crBk);
               }

               // draw pushed-in or popped-out edge
               if( bSelected || bChecked ) {
                  RECT rc2 = rcButn;
                  dc.DrawEdge(&rc2, bChecked ? BDR_SUNKENOUTER : BDR_RAISEDINNER, BF_RECT);
               }
               // draw the image
               ImageList_Draw(m_hImageList, iButton, dc, point.x, point.y, ILD_TRANSPARENT);
            }
            else {
               DrawBitmapDisabled(dc, iButton, point);
            }
         }
         else {
            // No image - look for custom checked/unchecked bitmaps
            CMenuItemInfo info;
            info.fMask = MIIM_CHECKMARKS | MIIM_TYPE;
            ::GetMenuItemInfo((HMENU)lpDrawItemStruct->hwndItem, lpDrawItemStruct->itemID, MF_BYCOMMAND, &info);
            if(bChecked || info.hbmpUnchecked != NULL) {
               BOOL bRadio = ((info.fType & MFT_RADIOCHECK) != 0);
               bHasImage = Draw3DCheckmark(dc, rcButn, bSelected, bDisabled, bRadio, bChecked ? info.hbmpChecked : info.hbmpUnchecked)==TRUE;
            }
         }

         // Draw item text
         int cxButn = m_szButton.cx;
         COLORREF colorBG = ::GetSysColor(bSelected ? COLOR_HIGHLIGHT : COLOR_MENU);
         if( bSelected || lpDrawItemStruct->itemAction==ODA_SELECT ) {
            RECT rcBG = rcItem;
            if( bHasImage ) rcBG.left += cxButn + s_kcxGap;
            HBRUSH hbr = hbrBack;
            if( bSelected ) hbr = (HBRUSH)LongToPtr((COLOR_HIGHLIGHT + 1));
            dc.FillRect(&rcBG, hbr);
         }

         // Calc text rectangle and colors
         RECT rcText = rcItem;
         rcText.left += cxButn + s_kcxGap + s_kcxTextMargin;
         rcText.right -= cxButn;
         dc.SetBkMode(TRANSPARENT);
         COLORREF colorText = ::GetSysColor(bDisabled ? (bSelected ? COLOR_GRAYTEXT : COLOR_3DSHADOW) : (bSelected ? COLOR_HIGHLIGHTTEXT : COLOR_MENUTEXT));

         // Font already selected by Windows
         if( bDisabled && (!bSelected || colorText==colorBG) ) {
            // Disabled - draw shadow text shifted down and right 1 pixel (unles selected)
            RECT rcDisabled = rcText;
            ::OffsetRect(&rcDisabled, 1, 1);
            DrawMenuText(dc, rcDisabled, pmd->lpstrText, ::GetSysColor(COLOR_3DHILIGHT), bDrawAccel);
         }
         DrawMenuText(dc, rcText, pmd->lpstrText, colorText, bDrawAccel); // finally!
      }
   }

   void DrawMenuText(CDCHandle& dc, RECT& rc, LPCTSTR lpstrText, COLORREF color, bool bDrawAccel)
   {
      int nTab = -1;
      for( int i=0; i < ::lstrlen(lpstrText); i++ ) {
         if(lpstrText[i]==_T('\t')) {
            nTab = i;
            break;
         }
      }
      dc.SetTextColor(color);
      UINT uFlags = DT_SINGLELINE | DT_VCENTER;
      if( !bDrawAccel ) uFlags |= DT_HIDEPREFIX;
      dc.DrawText(lpstrText, nTab, &rc, DT_LEFT | uFlags);
      if( nTab!=-1 ) dc.DrawText(&lpstrText[nTab + 1], -1, &rc, DT_RIGHT | uFlags);
   }

   void MeasureItem(LPMEASUREITEMSTRUCT lpMeasureItemStruct)
   {
      _MenuItemData2* pmd = (_MenuItemData2*)lpMeasureItemStruct->itemData;
      int cx, cy;

      if( pmd->fHidden && !m_bShowRecent ) {
         cx = cy = 0;
      }
      else if( pmd->fSeparator ) {
         // Separator - uses half system height and zero width
         cx = 0;
         cy = ::GetSystemMetrics(SM_CYMENU)/2;
      }
      else if( pmd->fExpander ) {  
         // Expander
         cx = 80; // minimum width of expander
         cy = ::GetSystemMetrics(SM_CYMENU)-4;
      }
      else {
         // Standard menu item
         // Compute size of text - use DrawText with DT_CALCRECT
         CWindowDC dc(NULL);
         HFONT hOldFont;
         if(pmd->fState & MFS_DEFAULT) {
            // Need bold version of font
            LOGFONT lf;
            m_fontMenu.GetLogFont(lf);
            lf.lfWeight += 200;
            CFont fontBold;
            fontBold.CreateFontIndirect(&lf);
            ATLASSERT(fontBold.m_hFont != NULL);
            hOldFont = dc.SelectFont(fontBold);
         }
         else {
            hOldFont = dc.SelectFont(m_fontMenu);
         }

         RECT rcText = { 0, 0, 0, 0 };
         dc.DrawText(pmd->lpstrText, -1, &rcText, DT_SINGLELINE | DT_LEFT | DT_VCENTER | DT_CALCRECT);
         cx = rcText.right - rcText.left;
         dc.SelectFont(hOldFont);

         LOGFONT lf;
         m_fontMenu.GetLogFont(lf);
         cy = lf.lfHeight;
         if( cy<0 ) cy = -cy;
         cy += 8;

         // Height of item is the bigger of these two
         cy = max(cy, (int)m_szButton.cy);

         // Width is width of text plus a bunch of stuff
         cx += 2 * s_kcxTextMargin;   // L/R margin for readability
         cx += s_kcxGap;              // space between button and menu text
         cx += 2 * m_szButton.cx;     // button width (L=button; R=empty margin)
         // Windows adds 1 to returned value
         cx -= ::GetSystemMetrics(SM_CXMENUCHECK) - 1;

      }

      // Add space for the dividing border between hidden/visible items
      if( m_bShowRecent && pmd->fHidden ) {
         if( !pmd->fPrevHidden ) cy++;
         if( !pmd->fNextHidden ) cy++;
      }

      lpMeasureItemStruct->itemWidth = cx;
      lpMeasureItemStruct->itemHeight = cy;
   }
};


class CRecentCommandBarCtrl : public CRecentCommandBarCtrlImpl<CRecentCommandBarCtrl>
{
public:
   DECLARE_WND_SUPERCLASS(_T("WTL_RecentCommandBar"), GetWndClassName())
};

#ifdef _WTL_USE_MDI
typedef CRecentCommandBarCtrl CRecentMDICommandBarCtrl;
#endif

#endif // __ATLCTRLWR_H__
